/**
A multi shaped mine sweeper game
SDLHexamine  Copyright (C) 2009-2010  Andematunum-Software
(andematunum-software@googlegroups.com)

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "resources.h"
#include <string.h>
#include "SDL.h"
#include "SDL_image.h"

extern SDL_Surface* screen;

Resources* Resources::instance_ = NULL;

static auto_ptr<SDL_Surface> IMG_SafeLoad (const char* filename) {
  SDL_Surface* surf = IMG_Load(filename);
  if (surf == NULL) {
    char* buf = new char[128];
    sprintf(buf,"Unable to load an image: %s", filename);
    throw buf;
  }
  SDL_Surface* dispsurf = SDL_DisplayFormatAlpha(surf);
  SDL_FreeSurface(surf);
  return auto_ptr<SDL_Surface>(dispsurf);
}

void Resources::load_all_ () {
  surfaces_["covered"] = IMG_SafeLoad("data/covered.png");
  surfaces_["safe"]    = IMG_SafeLoad("data/safe.png");
  surfaces_["boom"]    = IMG_SafeLoad("data/boom.png");
  
  auto_ptr<SDL_Surface> all_numbers_p = IMG_SafeLoad("data/numbers.png");
  SDL_Surface* all_numbers = all_numbers_p.get();
  SDL_Rect src = {0, 0, TILE_W, TILE_H};
  SDL_Rect dst = {0, 0, TILE_W, TILE_H};
  
  // This is very tricky: the ALPHA channel must be disabled from
  // the source surface because the destination surface is empty,
  // so any RGBA->RGBA blit would combine with empty pixels and lead
  // to empty display.
  Uint32 alpha_value = all_numbers->format->alpha;
  SDL_SetAlpha(all_numbers,~SDL_SRCALPHA,0);

  for (int k = 0; k < 6; k++) {
    SDL_Surface* tmp = SDL_CreateRGBSurface(
     SDL_ANYFORMAT,
     TILE_W,
     TILE_H,
     0,0,0,0,0
    );
    char buf[2];
    sprintf(&buf[0],"%d",k);
    SDL_Surface* num = SDL_DisplayFormatAlpha(tmp);
    surfaces_[buf] = auto_ptr<SDL_Surface>(num);
    SDL_FreeSurface(tmp);
    
    // Because any new surface is transparent by default.
    SDL_SetAlpha(num,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);

    SDL_BlitSurface(all_numbers,&src,num,&dst);
    src.x += TILE_W;
  }
}

/** Automatic thanks to smart pointers.
void Resources::free_all_ () {
}
*/

void Resources::test () {
  SDL_Rect dst = {0, 0, TILE_W, TILE_H};
  SDL_BlitSurface(get("covered"),NULL,screen,&dst);
  dst.x += TILE_W;
  SDL_BlitSurface(get("safe"),NULL,screen,&dst);
  dst.x += TILE_W;
  SDL_BlitSurface(get("boom"),NULL,screen,&dst);
  dst.x += TILE_W;

  for (int k = 1; k <= 6; k++) {
    char buf[2];
    sprintf(&buf[0],"%d",k);
    SDL_BlitSurface(get(buf),NULL,screen,&dst);
    dst.x += TILE_W;
  }

  SDL_Flip(screen);
}

